package iOran;

import java.io.File;
import java.util.Scanner;

/**
 * O programa deve ler um arquivo do disco e rastrear o seu codigo que sao os
 * 5 primeiros caracteres do arquivo. O rastreio deve ser feito por blocos de
 * caracteres de tamanho definido pelo usuario.
 *
 * @author Isabela Maia
 * @author Leonardo Lemos
 * @author Ruan Carvalho
 */
public class Arquivo {

    private String codigo;      //campo codigo do arquivo
    private String data;        //campo data do arquivo
    private String descricao;   //campo descrição do arquivo
    private String caminhoArq;  //caminho para localização do arquivo em disco
    private int tamanhoBloco;   //tamanho especificado para cada bloco/pagina
    private int pagina = 0;     //numero de paginas pesquisadas
    private Scanner input;      //intrada de dados do disco

    public void setTamanhoBloco(int tamanho) {
        this.tamanhoBloco = tamanho;
    }

    public String getCodigo() {
        return (this.codigo);
    }

    public String getDescricao() {
        return (this.descricao);
    }

    public String getData() {
        return (this.data);
    }

    public int getPagina() {
        return (this.pagina);
    }

   /**
    * Realiza a validacao do caminho do arquivo
    * inicializa o arquivo com o caminho especificado
    *
    */
    public boolean validarCaminho(String caminhoArq) {

        File arquivo = new File(caminhoArq);
        // se o caminho for um arquivo, o caminho é valido
        if (arquivo.isFile()) { 
            this.caminhoArq = caminhoArq;
            return (true);
        } else {
            return (false);
        }
    }
    
    /**
     * reseta o numero da pagina e o indice de leitura do input para que a
     * pesquisa possa ser refeita quantas vezes for preciso sem a nessecidade
     * de fechar o programa
     */
    public boolean prepararPesquisa() {
        try {
            input = new Scanner(new File(caminhoArq));
            this.pagina = 0;
            return (true);
        } catch (Exception e) {
            return (false);
        }
    }

    /**
     * Retorna a pagina de String com o tamanho especificado (em bytes) pelo
     * usuario. Essa pagina é carregada a partir do arquivo em disco para que
     * seja feita a busca.
     */
    public String carregarPagina() {
        String linha;
        StringBuilder contents = new StringBuilder();

        /* Tenta carregar o tamanho especificado, se nao conseguir é porque o
         arquivo chegou ao fim e devemos retornar a string que conseguimos até
         ao final*/
        try {
            /*enquanto a linha for diferente de null(que representa que o arquivo acabou) e
             o tamanho do contents for menor que o bloco solicitado(que é o limite da pagina)*/
            while ((linha = input.nextLine()) != null && contents.toString().length() < tamanhoBloco) {
                contents.append(linha);
                contents.append(System.getProperty("line.separator"));
            }
        } catch (Exception e) {
        }
        this.pagina++;
        return (contents.toString());
    }

    /**
     * recebe por parametro o codigo a ser localizado e a pagina onde será
     * realizada a pesquisa.
     */
    public boolean rastreioSequencial(String codigo, String bloco) {
        //recebe 1 para nao pegar a quebra de linha
        int inicial = 1;
        int indice = 0;
        String linhaDePesquisa = new String();
        String codigoLinha = new String();
        //enquanto o indice inicial (inicial) for menor que o indice final do bloco
        while (inicial < bloco.length()) {
            /* localiza a primeira quebra de linha a partir do indice inicial (inicial)
             e retorna seu indice na String. Isso marca uma linha*/
            indice = bloco.indexOf('\n', inicial);
            /*A linha de pesquisa será a medida do indice inicial (inicial)
             até o indice onde foi encontrada a quebra de linha(indice)*/
            linhaDePesquisa = bloco.substring(inicial, indice);
            // A pesquisa será realizada com os 5 primeiros caracteres da linha de pesquisa
            codigoLinha = linhaDePesquisa.substring(0, 5);
            if (codigoLinha.compareTo(codigo) == 0) {
                this.codigo     = linhaDePesquisa.substring(0, 5);
                this.data       = linhaDePesquisa.substring(5, 15);
                this.descricao  = linhaDePesquisa.substring(15, linhaDePesquisa.length());
                return (true);
            }
            /*O indice inicial (inicial) da proxima linha será o indice onde foi
             encontrada a quebra de linha mais um*/
            inicial = indice + 1;
        }
        return (false);
    }

    /**
     * Realiza o rastreio no bloco carregado. Se ele encontrar o codigo procurado,
     * ele para a pesquisa, se nao encontrar carrega um novo bloco
     */
    public boolean realizarRastreio(String codigo) {
        String bloco = new String();
        boolean result;
        do {
            //bloco vai receber a pagina carregada
            bloco = this.carregarPagina();
            result = rastreioSequencial(codigo, bloco);
            /*enquanto result nao for verdadeiro e o tamanho da pagina carregada(bloco)
             nao for menor que o tamanho especificado (caso seja menor, significa
             que o arquivo em disco acabou)*/
        } while (!result && bloco.length() >= tamanhoBloco);
        return (result);
    }
}
